home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / System 7.0 Samples / AEObject-Edition1.0.2 Sample / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-18  |  33.3 KB  |  920 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. *
  3. *  Apple Developer Technical Support
  4. *
  5. *  Menu handling routines
  6. *
  7. *  Program:    AEObject-Edition Sample
  8. *  File:       Menu.c -    C Source
  9. *
  10. *  by:         C.K. Haun <TR>
  11. *
  12. *  Copyright © 1990-1992 Apple Computer, Inc.
  13. *  All rights reserved.
  14. *
  15. *------------------------------------------------------------------------------
  16. * This file handles menu stuff, swapping checkmarks, handling simple dialog 
  17. * boxes, and the like.  If it happens because of a menu selection, it comes through
  18. * here.
  19. *----------------------------------------------------------------------------*/
  20.  
  21. #define __SAMPMENU__
  22.  
  23. #pragma segment Menu
  24.  
  25. #include "Sampdefines.h"
  26. short pItemChecked;
  27.  
  28. static void SampleHelpDialog(void);
  29. static void DoAbout(void);
  30. CursHandle pCursHand = nil;
  31.  
  32.  
  33. #pragma segment Menu
  34. /* DoSelected is called from the main event loop in response to a 
  35. *   MenuSelect or MenuKey action.  Some events are handled here,
  36. *   some just set options.
  37. */
  38.  
  39. /* the long passed is the result from MenuSelect or MenuKey */
  40. /* this passes back a Boolean, which I don't use right now. */
  41. Boolean DoSelected(long val)
  42. {
  43.     short loval, hival;
  44.     Boolean temp = false;
  45.     Str63 menuText;
  46.     windowCHandle tempWC;
  47.     short tempActionOut;
  48.     loval = LoWord(val);
  49.     hival = HiWord(val);
  50.     if(FrontWindow())tempWC = (windowCHandle)GetWRefCon(FrontWindow());    
  51.     switch (hival) {                                        /* switch off the menu number selected */
  52.         case kGetDataSubmenu:
  53.             SendGetData(loval);
  54.             break;
  55.         case kSetDataSubmenu:
  56.             SendSetData(loval);
  57.         break;
  58.         case kAppleMenu:                                    /* Apple menu */
  59.             if (loval != kAboutItem) {                               /* if this was not About, it's a DA */
  60.                 DoDaCall(gAppleMenuHandle, loval);
  61.             } else {
  62.                 DoAbout();                                  /* do about box */
  63.             }
  64.             break;
  65.         case kFileMenu:                                     /* File menu */
  66.             switch (loval) {
  67.                 WindowPtr tempW;
  68.                 AliasHandle tempAlias;                      /* for SaveAs */
  69.                 windowCHandle tempName;
  70.                 case kNewItem:
  71.                     if (!(tempW = AddNewWindow(true)))      /* Call AddNewWindow.  If it fails, tell */
  72.                     {
  73.                         ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
  74.                         Alert(kNoMoreWindows, upp);         /* user why */
  75.                         DisposeRoutineDescriptor(upp);
  76.                    }
  77.                     else
  78.                         ChangePlane(tempW);
  79.                     break;
  80.                 case kOpenItem:
  81.                     OpenFile(nil);                          /* open a file, nil says that I am not passing a */
  82.                     /* FileSpec, promt the user for a name */
  83.                     break;
  84.                 case kCloseItem:                            /* call the close procedure for this window */
  85.                     (ProcPtr)((*tempWC)->closeMe)(FrontWindow());
  86.                     break;
  87.                 case kSaveItem:                             /* call the save procedure for this window */
  88.                     HLock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
  89.                     (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
  90.                     HUnlock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
  91.                     break;
  92.                 case kSaveAsItem:                           /* save under a different name */
  93.                     HLock((Handle)tempWC);
  94.                     tempName = (windowCHandle)GetWRefCon(FrontWindow());
  95.                     /* save off the old alias in case the person cancels */
  96.                     tempAlias = (*tempName)->fileAliasHandle;
  97.                     /* get an empty handle and store it in the alias place, this tells the Save */
  98.                     /* function that this file has not yet been saved, so put up a SF box */
  99.                     (*tempName)->fileAliasHandle = (AliasHandle)NewHandle(0);
  100.                     (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
  101.                     /* see if they really saved (by checking the size of the alias) and if they have */
  102.                     /* get rid of the alias you saved */
  103.                     if (GetHandleSize((Handle)(*tempName)->fileAliasHandle) == nil) {
  104.                         DisposeHandle((Handle)(*tempName)->fileAliasHandle);
  105.                         (*tempName)->fileAliasHandle = tempAlias;
  106.                     } else {
  107.                         DisposeHandle((Handle)tempAlias);
  108.                     }
  109.                     HUnlock((Handle)tempWC);
  110.                     break;
  111.                     
  112.                 case kPrintItem:
  113.                     PrintIt(FrontWindow(), true);
  114.                     break;
  115.                 case kPreferences:
  116.                     DoPreferences();
  117.                     break;
  118.                 case kQuitItem:
  119.                     PrepQuit();                             /* Call PrepQuit, which sets our quit flag, so we */
  120.                     /* quit the next time through the event loop. The */
  121.                     /* AEQuit handler also calls this routine */
  122.                     break;
  123.             }
  124.             break;
  125.         case kEditMenu:
  126.             /* edit menu junk */
  127.             switch (loval) {
  128.                 case kUndoItem:
  129.                     UndoLast();                             /* Undoes the last action in the frontmost window */
  130.                     break;
  131.                     /* all the C/C/P stuff acts _first_ on any active TextEdit records. */
  132.                     /* if there aren't any, then it goes to other stuff */
  133.                 case kCutItem:
  134.                     if (!CutText()){
  135.                         if((*tempWC)->hasSelection){
  136.                         CutGraphic(tempWC);
  137.                         } else {
  138.                         CutSubscription();}}
  139.                     break;
  140.                 case kCopyItem:
  141.                     if (!CopyText()){
  142.                         if((*tempWC)->hasSelection){
  143.                         CopyGraphic(tempWC);
  144.                         } else {
  145.                         CopySubscription();}}
  146.                     break;
  147.                 case kPasteItem:
  148.                     /* pasting text has precidence over subscriptions.  Just because I felt like it */
  149.                     /* vary to suit the needs of your users and application */
  150.                     if (!PasteText())
  151.                         PasteSubscription();
  152.                     break;
  153.                 case kClearItem:
  154.                     /* Clear item acts as 'cancel' for the selected section */
  155.                     if (!ClearText()){
  156.                         if((*tempWC)->hasSelection){
  157.                         ClearGraphic(tempWC);
  158.                         } else {
  159.                         DeleteSubscriber();}}
  160.                     break;
  161.                 case kPublishItem:
  162.                     /* see if there is any text */
  163.                     if (HasTESelection((windowCHandle)GetWRefCon(FrontWindow())))
  164.                         CreatePublisher(kGenericTEXTWord, false, nil);
  165.                     else
  166.                         CreatePublisher(kGenericPICTWord, false, nil);        /* in Publish.c */
  167.                     break;
  168.                 case kSubscribeItem:
  169.                     DoSubscribe();                          /* in Subscribe.c */
  170.                     break;
  171.                 case kSoptionsItem:
  172.                     DoOptions(gShowingSecHandle);           /* in Subscribe.c.  Same */
  173.                     /* function is called for a publish or subscribe section */
  174.                     break;
  175.                 case kBorders:
  176.                     if (gShowingAll) {
  177.                         gShowingAll = false;
  178.                         GetIndString(menuText, kGeneralStrings, kShowBString);
  179.                         
  180.                         SetMenuItemText(gEditMenuHandle, kBorders, menuText);
  181.                         
  182.                         /* and get rid of any currently shown borders, even the */
  183.                         /* last clicked in one */
  184.                         DeBorderSelection();
  185.                         KillTextBorders();
  186.                     } else {
  187.                         gShowingAll = true;
  188.                         GetIndString(menuText, kGeneralStrings, kHideBString);                        
  189.                         SetMenuItemText(gEditMenuHandle, kBorders, menuText);
  190.                         ShowAllTextBorders();
  191.                     }
  192.                     /* make sure they get redrawn */
  193.                     InvalRect(&(FrontWindow()->portRect));                    
  194.                     break;
  195.                 case kClapNum:
  196.                     if (((WindowPeek)FindClipWindow())->visible) {
  197.                         CloseClip(FindClipWindow());
  198.                     } else {
  199.                         ShowWindow(FindClipWindow());
  200.                         AddToWindowMenu(FindClipWindow(), nil);
  201.                         ChangePlane(FindClipWindow());
  202.                         GetIndString(menuText, kGeneralStrings, kHideClipString);                        
  203.                         SetMenuItemText(gEditMenuHandle, kClapNum, menuText);
  204.                         
  205.                     }
  206.                     break;
  207.                     
  208.             }                                               /* edit menu switch */
  209.             break;
  210.         case kToolsMenu:
  211.             switch (loval) {
  212.                 /* Clean this up, this is silly, I say, this is silly son..... */
  213.                 case kLineItem:
  214.                     tempActionOut = kDrawLine;
  215.                     break;
  216.                 case kRectItem:
  217.                     tempActionOut = kDrawRect;
  218.                     break;
  219.                 case kOvalItem:
  220.                     tempActionOut = kDrawOval;
  221.                     break;
  222.                 case kTextBoxItem:
  223.                     tempActionOut = kTextBox;
  224.                     break;
  225.                 case kSelectItem:
  226.                     tempActionOut = kSelectStuff;
  227.                     break;
  228.                     
  229.             }
  230.             /* these set the current action for the front window, set the */
  231.             /* cursor for the selected tool, and check the correct menu item */
  232.             KillSelection((windowCHandle)GetWRefCon(FrontWindow()));
  233.             SetCurAction(tempActionOut);
  234.             SetMyCursor(loval);
  235.             SwitchChecks(loval);
  236.             break;
  237.         case kAEMenu:
  238.             switch (loval) {
  239.                 case kInteractionItem:
  240.                     SetInteractionLevels();
  241.                     break;
  242.                 case kAddressItem:
  243.                     SetTargetAddress();
  244.                     break;
  245.                 case kReplyItem:
  246.                     SetReplyMode();
  247.                     break;
  248.                 case kShowAEWind:
  249.                     ToggleAEWindow();
  250.                     break;
  251.                     /* set the characteristics that will make up the object specifier */
  252.                     /* for the window to be acted upon.  Jeez, pendantic enough, or what? */
  253.                     
  254.                 case kWindowObjChar:
  255.                 case kTextObjectChar:
  256.                 case kShapeObjectChar:
  257.                     DoObjectDefinition((loval - kWindowObjChar) + kSetWindowObject);
  258.                     break;
  259.                 case kSendGetDataAE:
  260.                     /* has sub-menu, should never be returned */
  261.                     break;
  262.                     
  263.                 case kSendSetDataAE:
  264.                     /* has sub-menu, should never be returned */
  265.                     break;
  266.                 default:
  267.                     
  268.                     break;
  269.             }
  270.             break;
  271.         case kEditionMenu:
  272.         DoEditionAdditional(loval);
  273.         break;
  274.         case kWindowMenu:
  275.             WindowToFront(loval,nil);
  276.             break;
  277.         case kColorMenu:
  278.  
  279.         CheckItem(gColorMenuHandle, gCurrentColor,false);
  280.         CheckItem(gColorMenuHandle, loval,true);
  281.         if(loval == kCustomColorItem){Point where = {-1,-1};
  282.         Str255 thewords;
  283.         RGBColor newColor;
  284.         GetIndString(thewords,kGeneralStrings,kCPick);
  285.         if(GetColor(where,thewords,&gColorArray[gCurrentColor],&newColor))gColorArray[kCustomColorItem] = newColor;
  286.         }
  287.         gCurrentColor = loval;
  288.                 
  289.         
  290.         break;
  291.         case kHMHelpMenuID:
  292.             /* I only care about this one item.  If anything else is returned here, I don't know what */
  293.             /* it is, so I leave it alone.  Remember, the Help Manager chapter syas that */
  294.             /* Apple reserves the right to add and change things in the Help menu */
  295.             if (loval == gHelpItem)
  296.                 SampleHelpDialog();
  297.             break;
  298.             
  299.     }
  300.     HiliteMenu(0);
  301.     return(temp);   /* I have never actually use this return value in 6 years, but I might some day.  */
  302.     /* I always put it in because it _could_ be real handy */
  303. }
  304.  
  305. /* end DoSelected */
  306.  
  307. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  308. /* like to perform some action or just know when a DA is opened in your */
  309. /* layer.  Can be handy to track memory problems when a DA is opened */
  310. /* with an Option-open */
  311. void DoDaCall(MenuHandle themenu, long theit)
  312. {
  313.     long qq;
  314.     char DAname[255];
  315.     GetMenuItemText(themenu, theit, &DAname);
  316.     qq = OpenDeskAcc(DAname);
  317. }
  318.  
  319. /* end DoDaCall */
  320.  
  321. /* PrepQuit sets the stop flag.  Called from the menu or from the */
  322. /* quit AppleEvent handler.  It also calls the close function on all open windows, and */
  323. /* cancels the quit if the user stops things */
  324. /* Also unregisters the ClipBoard section, if one exists */
  325. OSErr PrepQuit(void)
  326. {
  327.     WindowPtr tempFront = (WindowPtr)LMGetWindowList();
  328.     windowCHandle tempWCH;
  329.     gStop = true;
  330.     while (tempFront) {
  331.         WindowPtr tempHolder;
  332.         tempHolder = (WindowPtr)((WindowPeek)tempFront)->nextWindow;
  333.         tempWCH = (windowCHandle)GetWRefCon(tempFront);
  334.         (ProcPtr)((*tempWCH)->closeMe)(tempFront);          /* call this closing routine */
  335.         tempFront = tempHolder;                             /* yeah, yeah , a little duplication.  */
  336.         if (gStop == false)
  337.             break;                                          /* if this is false, they hit cancel in the close routine */
  338.     }
  339.     if (gStop) {
  340.         extern short gClipHasContents;
  341.         extern SectionHandle gClipSection;
  342.         /* clear the clipboard */
  343.         /* if it has a section, we have to tell the Edition Manager we're done with it */
  344.         if (gClipHasContents == kClipHasSub) {
  345.             UnRegisterSection(gClipSection);
  346.             DisposeHandle((Handle)(*gClipSection)->alias);
  347.             DisposeHandle((Handle)gClipSection);
  348.             gClipSection = nil;
  349.             gClipHasContents = kClipEmpty;
  350.         }
  351.         return(noErr);                                      /* quit will happen */
  352.     } else {
  353.         return(userCanceledErr);
  354.     }                                                       /* user stopped the termination */
  355. }
  356.  
  357. /* end PrepQuit */
  358.  
  359. /* SetUndo sets the text of the Undo item based on the last action in */
  360. /* the current window, if fromRecord is true, else use*/
  361. /* undoNow */
  362. void SetUndo(short undoNow, Boolean fromRecord)
  363. {Str255 undoString;
  364.     windowCHandle temp;
  365.     if (FrontWindow() == nil) {
  366.         GetIndString(undoString, kUndoStringsRes, 1);
  367.         SetMenuItemText(gEditMenuHandle, kUndoItem, &undoString);
  368.         DisableItem(gEditMenuHandle, kUndoItem);
  369.     } else {
  370.         temp = (windowCHandle)GetWRefCon(FrontWindow());
  371.         if (fromRecord)
  372.             undoNow = (*temp)->undoAction;
  373.         else
  374.             (*temp)->undoAction = undoNow;
  375.         GetIndString(undoString, kUndoStringsRes, undoNow + 1);
  376.         SetMenuItemText(gEditMenuHandle, kUndoItem, &undoString);
  377.         if (undoNow)
  378.             EnableItem(gEditMenuHandle, kUndoItem);
  379.         else
  380.             DisableItem(gEditMenuHandle, kUndoItem);
  381.     }
  382. }
  383.  
  384. /* end SetUndo */
  385.  
  386. /* SetMyCursor sets the cursor to the correct shape for the */
  387. /* tool in use */
  388. void SetMyCursor(short myCurs)
  389. {
  390.     if (pCursHand != nil) {
  391.         ReleaseResource((Handle)pCursHand);
  392.         pCursHand = nil;
  393.     }
  394.     if (myCurs == 0) {
  395.         InitCursor();
  396.     } else {
  397.         switch (myCurs) {
  398.             case kLineItem:
  399.                 pCursHand = GetCursor(crossCursor); /* in the system file */
  400.                 break;
  401.             case kRectItem:
  402.             case kTextBox:
  403.             case kOvalItem:
  404.                 pCursHand = (CursHandle)GetResource('CURS', 126 + myCurs);
  405.                 break;
  406.             case kSelectItem:
  407.                 pCursHand = (CursHandle)GetResource('CURS', 131);
  408.                 break;
  409.         }
  410.         SetCursor(*pCursHand);
  411.     }
  412. }
  413.  
  414. /* end SetMyCursor */
  415.  
  416. /* SwitchChecks sets the checking of the tool menu items  */
  417. void SwitchChecks(short itemNow)
  418. {
  419.     Boolean how;
  420.     if (pItemChecked == itemNow) {                          /* is this item currently checked?  If so */
  421.         how = false;                                        /* uncheck it and set action to nil */
  422.         SetCurAction(kNoAction);
  423.         InitCursor();
  424.         pItemChecked = 0;
  425.     } else {
  426.         CheckItem(gToolMenuHandle, pItemChecked, false);
  427.         pItemChecked = itemNow;
  428.         how = true;
  429.     }
  430.     CheckItem(gToolMenuHandle, itemNow, how);
  431. }
  432.  
  433. /* end SwitchChecks */
  434.  
  435. /* SetCurAction sets the action value in the window record */
  436. void SetCurAction(short actionIn)
  437. {
  438.     if (FrontWindow() != nil) {
  439.         windowCHandle shortname = (windowCHandle)GetWRefCon(FrontWindow());
  440.         HLock((Handle)shortname);
  441.         (*shortname)->currentAction = actionIn;
  442.         HUnlock((Handle)shortname);
  443.     }
  444. }
  445.  
  446. /* end SetCurAction */
  447.  
  448. void SetWMenus(Boolean how)
  449. {
  450.     short qq;
  451.     if (how) {
  452.         EnableItem(gFileMenuHandle, kCloseItem);
  453.         EnableItem(gFileMenuHandle, kPrintItem);
  454.         EnableItem(gFileMenuHandle, kSaveItem);
  455.         EnableItem(gFileMenuHandle, kSaveAsItem);
  456.         EnableItem(gEditMenuHandle, kSubscribeItem);
  457.         EnableItem(gToolMenuHandle, 0);
  458.         for (qq = 1; qq < 5; qq++) {
  459.             EnableItem(gToolMenuHandle, qq);
  460.         }
  461.     } else {
  462.         DisableItem(gFileMenuHandle, kCloseItem);
  463.         DisableItem(gFileMenuHandle, kPrintItem);
  464.         DisableItem(gFileMenuHandle, kSaveItem);
  465.         DisableItem(gFileMenuHandle, kSaveAsItem);
  466.         DisableItem(gEditMenuHandle, kSubscribeItem);
  467.         DisableItem(gToolMenuHandle, 0);                    /* kill this whole thing */
  468.     }
  469.     DrawMenuBar();
  470. }
  471.  
  472. /* end SetWMenus */
  473.  
  474. /* AdjustMenus is called right before MenuSelect or MenuKey to set the state of */
  475. /* the menu items for the frontmost window.  */
  476. void AdjustMenus(windowCHandle tempCH,WindowPtr currentWindow)
  477. {
  478.     Str63 menuText;
  479.     register qq;
  480.     Str63 item, name;
  481.     short count;
  482.     short wKind;
  483.     /* Do we currently */
  484.     /* have an area selected? */
  485.     if(currentWindow)
  486.         wKind = ((WindowPeek)currentWindow)->windowKind;
  487.     if (tempCH && ((*tempCH)->hasSelection || HasTESelection(tempCH)))            /* Yes, enable the Publish item */
  488.         EnableItem(gEditMenuHandle, kPublishItem);
  489.     else                                                    /* No, dim the publish item */
  490.         DisableItem(gEditMenuHandle, kPublishItem);
  491.     
  492.     /* Next, are we showing a border around a subscriber or */
  493.     /* publisher? If so, then we allow the user to bring up */
  494.     /* the Options dialog */
  495.     if (gShowPub || gShowSub) {
  496.         EnableItem(gEditMenuHandle, kSoptionsItem);
  497.         EnableItem(gEditionMenuHandle,kGetSecInfo);
  498.     } else {
  499.         DisableItem(gEditMenuHandle, kSoptionsItem);
  500.         DisableItem(gEditionMenuHandle,kGetSecInfo);
  501.     }
  502.        /* is there a document or AEStatus window in front? */
  503. if (currentWindow != nil && (wKind == kDocumentWindow || wKind == kAEStatusWindow)) {
  504.         EnableItem(gFileMenuHandle, kSaveItem);
  505.         /* this following little if is based on a pickiness I have personally */
  506.         /* If the window has not yet been saved, include an ellipsis in the 'Save…' */
  507.         /* item, since the standard file box will be coming up. */
  508.         /* if it has been saved, then no dots, just 'Save' */
  509.         /* since there won't be a dialog */
  510.         if (GetHandleSize((Handle)(*tempCH)->fileAliasHandle) == nil) {
  511.             GetIndString(menuText, kGeneralStrings, kSaveDotsString);
  512.             SetMenuItemText(gFileMenuHandle, kSaveItem, menuText);
  513.         } else {
  514.             GetIndString(menuText, kGeneralStrings, kSaveNDotsString);
  515.             SetMenuItemText(gFileMenuHandle, kSaveItem, menuText);
  516.         }
  517.         } else {
  518.           DisableItem(gFileMenuHandle, kSaveItem);
  519.         }        
  520.     if (currentWindow != nil && wKind == kDocumentWindow ) {   /* is there a document window in front? */
  521.             /* I'm only allowing a text box if there are no other objects. */
  522.        if ((*tempCH)->boxHandle != nil || (*tempCH)->numShapes)
  523.             DisableItem(gToolMenuHandle, kTextBoxItem);
  524.         else
  525.             EnableItem(gToolMenuHandle, kTextBoxItem);
  526.         
  527.     } else {
  528.       
  529.         /* make sure the undo and show borders items are right */
  530.         SetUndo(nil, nil);
  531.         GetIndString(menuText, kGeneralStrings, kShowBString);
  532.         SetMenuItemText(gEditMenuHandle, kBorders, menuText);
  533.         DisableItem(gEditMenuHandle, kBorders);
  534.     }
  535.     /* if there is a subscriber, or a subscription on the clipboard, or a TEselection enable the edit commands */
  536.     if (tempCH && ((*tempCH)->hasSelection || gShowSub || HasTESelection(tempCH))) {
  537.         EnableItem(gEditMenuHandle, kCutItem);
  538.         EnableItem(gEditMenuHandle, kCopyItem);
  539.         EnableItem(gEditMenuHandle, kClearItem);
  540.     } else {
  541.         DisableItem(gEditMenuHandle, kCutItem);
  542.         DisableItem(gEditMenuHandle, kCopyItem);
  543.         DisableItem(gEditMenuHandle, kClearItem);
  544.     }
  545. /* uuuh, sorry, this 'if' got a little out of hand */
  546. if ((tempCH != nil) && (gClipHasContents == kClipHasSub || (gClipHasContents == kClipHasText && (*tempCH)->boxHandle != nil)) &&  wKind == kDocumentWindow) {
  547.         EnableItem(gEditMenuHandle, kPasteItem);
  548.     } else {
  549.         DisableItem(gEditMenuHandle, kPasteItem);
  550.     }
  551.     if (currentWindow) {
  552.         EnableItem(gFileMenuHandle, kCloseItem);
  553.     } else {
  554.         DisableItem(gFileMenuHandle, kCloseItem);
  555.     }
  556.     /* check frontmost window in the window menu */
  557.     if (currentWindow) {
  558.         count = CountMItems(gWindowMenuHandle);
  559.         GetWTitle(currentWindow, name);
  560.         for (qq = 1; qq < count + 1; qq++)
  561.             CheckItem(gWindowMenuHandle, qq, false);
  562.         for (qq = 1; qq < count + 1; qq++) {
  563.             GetMenuItemText(gWindowMenuHandle, qq, &item);
  564.             if (EqualString(item, name, false, false)) {
  565.                 CheckItem(gWindowMenuHandle, qq, true);
  566.             }
  567.         }
  568.     } 
  569. }
  570.  
  571. /* Just an example, since I had to have something to do when you select */
  572. /* my Help item */
  573. void SampleHelpDialog(void)
  574. {
  575.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  576.     short itemhit = 0;
  577.     ModalFilterUPP upp = NewModalFilterProc(standardDialogFilter);
  578.  
  579.     SetDialogDefaultItem(tdial, ok);
  580.     while (itemhit != 1) {
  581.         ModalDialog(upp, &itemhit);
  582.     }
  583.     DisposeRoutineDescriptor(upp);
  584.     DisposeDialog(tdial);
  585. }
  586.  
  587. /* The about box.   */
  588. void DoAbout(void)
  589. {
  590.     DialogPtr tdial = GetNewDialog(kAboutBox, nil, (WindowPtr)-1);
  591.     short hitItem = 0;
  592.     short tempItem;
  593.     Handle tempHandle;
  594.     Rect tempRect;
  595.     ModalFilterUPP upp = NewModalFilterProc(aboutFilter);
  596.  
  597.     GetDialogItem(tdial, kBorderArea, &tempItem, &tempHandle, &tempRect);
  598.     SetDialogItem(tdial, kBorderArea, tempItem, (Handle)BorderDefault, &tempRect);
  599.     GetDialogItem(tdial, kArrowArea, &tempItem, &tempHandle, &tempRect);
  600.     SetDialogItem(tdial, kArrowArea, tempItem, (Handle)ArrowArea, &tempRect);
  601.     ShowWindow(tdial);
  602.     while (hitItem != ok) {
  603.         ModalDialog(upp, &hitItem);
  604.     }
  605.     DisposeRoutineDescriptor(upp);
  606.     DisposeDialog(tdial);
  607. }
  608.  
  609. /* this filter does the icon animation */
  610. pascal Boolean aboutFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
  611. {
  612.     Boolean returnVal = false;
  613.     static short pOffset = 1;
  614.     static Boolean pMovingRight = true;
  615.     
  616.     static long count;
  617.     long tilticks;
  618.     Handle topIcon, bottomIcon;
  619.     short tempItem;
  620.     Handle tempHandle;
  621.     Rect tempRect;
  622.     Rect idleRect, iconRect;
  623.     WindowPtr tempPort;
  624. #define kReturnKey 0xd
  625. #define kEnterKey 3
  626.     GetPort(&tempPort);
  627.     SetPort(theDialog);
  628.     if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
  629.         switch (theEvent->message & charCodeMask) {
  630.             case kReturnKey:
  631.             case kEnterKey:                                 /* enter key */
  632.                 /* This filters for Return or Enter as item 1, and Esc as item 2 */
  633.                     *itemHit = 1;                           /* change whatever the current item is to the OK item */
  634.                 /* now we need to invert the button */
  635.                 GetDialogItem(theDialog, ok, &tempItem, &tempHandle, &tempRect);
  636.                 HiliteControl(SnatchHandle(theDialog, ok), inButton);
  637.                 Delay(8, &tilticks);                        /* wait about 8 ticks so they can see it */
  638.                 HiliteControl(SnatchHandle(theDialog, ok), false);
  639.                 returnVal = true;
  640.                 break;
  641.             default:
  642.                 break;
  643.         }
  644.     } else {
  645.         /* Do fancy animation.  Hey, this sample is big, took a while to write, I should have */
  646.         /* a fancy about box.  Anyway, it only took 1/2 hour (I used DialogBits.c) */
  647.         GetDialogItem(theDialog, kArrowArea, &tempItem, &tempHandle, &tempRect);
  648.         idleRect.top = tempRect.top;
  649.         idleRect.bottom = idleRect.top + 32;
  650.         idleRect.left = ((((tempRect.right - tempRect.left) / 2))+tempRect.left)-16;
  651.         idleRect.right = idleRect.left + 32;
  652.         iconRect = idleRect;
  653.         if (pMovingRight) {
  654.             /* going <- -> */
  655.             topIcon = GetIcon(129);
  656.             bottomIcon = GetIcon(130);
  657.         } else {
  658.             topIcon = GetIcon(130);
  659.             bottomIcon = GetIcon(129);
  660.             
  661.         }
  662.         OffsetRect(&iconRect, 1 * pOffset, 0);
  663.         PlotIcon(&iconRect, topIcon);
  664.         ReleaseResource(topIcon);
  665.         iconRect = idleRect;
  666.         OffsetRect(&iconRect, -1 * pOffset, 0);
  667.         iconRect.bottom = tempRect.bottom;
  668.         iconRect.top = iconRect.bottom - 32;
  669.         PlotIcon(&iconRect, bottomIcon);
  670.         ReleaseResource(bottomIcon);
  671.         pMovingRight ? pOffset++ : pOffset--;
  672.         if (pMovingRight) {
  673.             if (iconRect.left <= tempRect.left)
  674.                 pMovingRight = false;
  675.         } else {
  676.             if (iconRect.right >= tempRect.right)
  677.                 pMovingRight = true;
  678.         }
  679.     }
  680.     SetPort(tempPort);
  681.     return(returnVal);
  682. }
  683.  
  684. /* borders the default button.  Not needed with the new Dialog Manager calls, see Tech Note #304 */
  685. pascal void BorderDefault(WindowPtr dwind, short dinum)
  686. {
  687. #pragma unused (dinum)
  688.     short itemtype;
  689.     Handle itemhandle;
  690.     Rect borderRect;
  691.     GetDialogItem(dwind, ok, &itemtype, &itemhandle, &borderRect);
  692.     /* ok is defined as 1 in the interfaces.  If you'd like another item outlined, */
  693.     /* change this number, of course. */
  694.     InsetRect(&borderRect, -4, -4);
  695.     PenSize(3, 3);
  696.     FrameRoundRect(&borderRect, 16, 16);
  697.     PenSize(1, 1);
  698. }
  699.  
  700. /* user item for the area the arrows traverse.  doesn't do much */
  701. pascal void ArrowArea(WindowPtr dwind, short dinum)
  702. {
  703. #pragma unused (dinum)
  704.     short itemtype;
  705.     Handle itemhandle;
  706.     Rect borderRect;
  707.     GetDialogItem(dwind, dinum, &itemtype, &itemhandle, &borderRect);
  708.     EraseRect(&borderRect);
  709. }
  710.  
  711. /* Our preferences dialog box */
  712. pascal void FrameBox(WindowPtr rDial, short dinum);
  713. void DoPreferences(void)
  714. {
  715.     DialogPtr tdial = CommonDStart(kPreferencesBox, nil, nil);
  716.     short kindI;
  717.     Handle HandL;
  718.     Rect itemRect;
  719.     short hitItem = 0;
  720.     
  721.     ShowWindow(tdial);
  722.     /* Set the controls to the previously stored preferences */
  723.     SetControlValue(SnatchHandle(tdial, kBringAEForwardCheck), gPreferences.bringAEUp);
  724.     SetControlValue(SnatchHandle(tdial, kVerboseCheck), gPreferences.verboseAE);
  725.     SetControlValue(SnatchHandle(tdial, kSaveWindCheck), gPreferences.saveWindDef);
  726.     SetControlValue(SnatchHandle(tdial, kSaveTextCheck), gPreferences.saveTextDef);
  727.     SetControlValue(SnatchHandle(tdial, kSaveShapeCheck), gPreferences.saveShapeDef);
  728.     SetControlValue(SnatchHandle(tdial, kSaveInteractCheck), gPreferences.saveInteract);
  729.     SetControlValue(SnatchHandle(tdial, kSaveTargetCheck), gPreferences.saveTarget);
  730.     SetControlValue(SnatchHandle(tdial, kSaveReplyCheck), gPreferences.saveReply);
  731.  
  732.     GetDialogItem(tdial, kFBox1, &kindI, &HandL, &itemRect);
  733.     SetDialogItem(tdial, kFBox1, userItem, (Handle)FrameBox, &itemRect);
  734.     GetDialogItem(tdial, kFBox2, &kindI, &HandL, &itemRect);
  735.     SetDialogItem(tdial, kFBox2, userItem, (Handle)FrameBox, &itemRect);
  736.     GetDialogItem(tdial, kFBox3, &kindI, &HandL, &itemRect);
  737.     SetDialogItem(tdial, kFBox3, userItem, (Handle)FrameBox, &itemRect);
  738.  
  739.     /* run the dialog */
  740.     while (hitItem != ok && hitItem != cancel) {
  741.          ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
  742.         ModalDialog(upp, &hitItem);
  743.         DisposeRoutineDescriptor(upp);
  744.         switch (hitItem) {
  745.             case 9:
  746.                 {
  747.                 ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
  748.                 Alert(350, upp);
  749.                 DisposeRoutineDescriptor(upp);
  750.                 }
  751.                 break;
  752.             case kBringAEForwardCheck:
  753.             case kVerboseCheck:
  754.             case kSaveWindCheck:
  755.             case kSaveTextCheck:
  756.             case kSaveShapeCheck:
  757.             case kSaveInteractCheck:
  758.             case kSaveTargetCheck:
  759.             case kSaveReplyCheck:
  760.             /* if they hit a checkbox, just toggle state */
  761.                 SetControlValue(SnatchHandle(tdial, hitItem), (GetControlValue(SnatchHandle(tdial, hitItem)) ? 0 : 1));
  762.                 break;
  763.             default:
  764.                 break;
  765.         }
  766.     }
  767.  
  768.     if (hitItem == ok) {
  769.         /* generate our new preferences */
  770.         gPreferences.bringAEUp = GetControlValue(SnatchHandle(tdial, kBringAEForwardCheck));
  771.         gPreferences.verboseAE = GetControlValue(SnatchHandle(tdial, kVerboseCheck));
  772.         gPreferences.saveWindDef = GetControlValue(SnatchHandle(tdial, kSaveWindCheck));
  773.         gPreferences.saveTextDef = GetControlValue(SnatchHandle(tdial, kSaveTextCheck));
  774.         gPreferences.saveShapeDef = GetControlValue(SnatchHandle(tdial, kSaveShapeCheck));
  775.         gPreferences.saveInteract = GetControlValue(SnatchHandle(tdial, kSaveInteractCheck));
  776.         gPreferences.saveTarget = GetControlValue(SnatchHandle(tdial, kSaveTargetCheck));
  777.         gPreferences.saveReply = GetControlValue(SnatchHandle(tdial, kSaveReplyCheck));        
  778.         gPreferences.prefsChanged = true;
  779.     }
  780.     DisposeDialog(tdial);
  781. }
  782.  
  783.  
  784. /* Draws a greay outline and some text around related items in a DialogBox */
  785. pascal void FrameBox(WindowPtr rDial, short dinum)
  786. {
  787.     Str63 wordsAre;
  788.     
  789.     Rect framer;
  790.     Rect tempR;
  791.     short itemIs;
  792.     short widthY;
  793.     Point thePen;
  794.     Point start, end;
  795.     Handle yeah;
  796.     GetIndString(&wordsAre, 129, dinum - 12);
  797.     GetDialogItem(rDial, dinum, &itemIs, &yeah, &framer);
  798.     widthY = StringWidth(&wordsAre);
  799.     
  800.     /* do the sides first */
  801.     /* left */
  802.     start.h = framer.left;
  803.     start.v = framer.top;
  804.     end.h = framer.left;
  805.     end.v = framer.bottom;
  806.     MoveTo(start.h, start.v);
  807.     LineTo(end.h, end.v);
  808.     MakeRect(&start, &end, &tempR);
  809.     PenPat(&qd.gray);
  810.     PenMode(notPatBic);
  811.     PaintRect(&tempR);
  812.     PenMode(srcCopy);
  813.     PenPat(&qd.black);
  814.     /* bottom */
  815.     start.h = framer.left;
  816.     start.v = framer.bottom;
  817.     end.h = framer.right;
  818.     end.v = framer.bottom;
  819.     MoveTo(start.h, start.v);
  820.     LineTo(end.h, end.v);
  821.     MakeRect(&start, &end, &tempR);
  822.     PenPat(&qd.gray);
  823.     PenMode(notPatBic);
  824.     PaintRect(&tempR);
  825.     PenMode(srcCopy);
  826.     PenPat(&qd.black);
  827.     /* right */
  828.     start.h = framer.right;
  829.     start.v = framer.bottom;
  830.     end.h = framer.right;
  831.     end.v = framer.top;
  832.     MoveTo(start.h, start.v);
  833.     LineTo(end.h, end.v);
  834.     start.h -= 3;
  835.     MakeRect(&start, &end, &tempR);
  836.     PenPat(&qd.gray);
  837.     PenMode(notPatBic);
  838.     PaintRect(&tempR);
  839.     PenMode(srcCopy);
  840.     PenPat(&qd.black);
  841.     
  842.     /* top line to start of text */
  843.     start.h = framer.left;
  844.     start.v = framer.top;
  845.     end.h = start.h + 10;
  846.     end.v = framer.top;
  847.     MoveTo(start.h, start.v);
  848.     LineTo(end.h, end.v);
  849.     start.h -= 3;
  850.     MakeRect(&start, &end, &tempR);
  851.     PenPat(&qd.gray);
  852.     PenMode(notPatBic);
  853.     PaintRect(&tempR);
  854.     PenMode(srcCopy);
  855.     PenPat(&qd.black);
  856.     MoveTo(end.h+3, end.v + 4);
  857.     DrawString(&wordsAre);
  858.     GetPen(&thePen);
  859.     /* end of text to corner */
  860.     start.h = thePen.h+4;
  861.     start.v = thePen.v - 4;
  862.     end.h = framer.right;
  863.     end.v = thePen.v - 4;
  864.     MoveTo(start.h, start.v);
  865.     LineTo(end.h, end.v);
  866.     start.h -= 3;
  867.     MakeRect(&start, &end, &tempR);
  868.     PenPat(&qd.gray);
  869.     PenMode(notPatBic);
  870.     PaintRect(&tempR);
  871.     PenMode(srcCopy);
  872.     PenPat(&qd.black);
  873.     
  874.     
  875. }
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885. /* This handles the EM Stuff menu */
  886. void DoEditionAdditional(short which)
  887. {
  888. EditionInfoRecord tempRecord;
  889. Str63 orgDate;
  890. Str63 modDate;
  891. Str15 typeCreator;
  892.    switch (which) {
  893.         case kExpandedItem:
  894.             gExpanded = gExpanded ? false : true;
  895.             CheckItem(gEditionMenuHandle, kExpandedItem, gExpanded);
  896.             
  897.             break;
  898.         case kGetSecInfo:
  899.             {
  900.             ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
  901.             GetEditionInfo(gShowingSecHandle, &tempRecord);
  902.             IUDateString(tempRecord.crDate, longDate, orgDate);
  903.             IUDateString(tempRecord.mdDate, longDate, modDate);
  904.             typeCreator[0]=9;
  905.             BlockMove((Ptr)&tempRecord.fdCreator, (Ptr)&typeCreator[1], 4);
  906.             typeCreator[5] = '/';
  907.             BlockMove((Ptr)&tempRecord.fdType, (Ptr)&typeCreator[6], 4);
  908.             ParamText(orgDate, modDate, typeCreator,tempRecord.container.theFile.name);
  909.             Alert(kEdInfo, upp);
  910.             DisposeRoutineDescriptor(upp);
  911.             }
  912.             break;
  913.       }
  914.  
  915. }
  916.  
  917.  
  918.  
  919. #undef __SAMPMENU__
  920.